package geometric3D;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

public class YZRectangle extends Rectangle {

	public YZRectangle() {
		super();

	}

	public YZRectangle(int width, int height, boolean isPositiveFaced) {
		super(width, height, isPositiveFaced);

	}

	public int getYSize(){
		return this.width;
	}
	public void setYSize(int ySize){
		this.width = ySize;
	}
	public int getZSize(){
		return this.height;
	}
	public void setZSize(int zSize){
		this.height= zSize;
	}
	
	public YZRectangle (Point positionPoint ,int ySize, int zSize, boolean isPositiveFaced){
		this.position = positionPoint;
		this.height = zSize;
		this.width = ySize;
		this.isPositiveFaced = isPositiveFaced;
	}

	@Override
	public String toString() {
		return "YZRectangle [position=" + position + ", isPositiveFaced="
				+ isPositiveFaced + ", getYSize()=" + getYSize()
				+ ", getZSize()=" + getZSize() + ", getArea()=" + getArea()
				+ "]\n";
	}
	public yLineSegment getYLineSegment(boolean isPositiveFaced){
		if(isPositiveFaced){
			return new yLineSegment(
					new Point(position.getX(), position.getY(), position.getZ()+getZSize()),
					new Point(position.getX(), position.getY(), position.getZ()+getZSize()));
		}else{
			return new yLineSegment(
					new Point(position.getX(), position.getY(), position.getZ()),
					new Point(position.getX(), position.getY(), position.getZ()));
		}
		
	}
	public zLineSegment getZLineSegment(boolean isPositiveFaced){
		if (isPositiveFaced) {
			return new zLineSegment(
					new Point(position.getX(), position.getY()+getYSize(), position.getZ()), 
					new Point(position.getX(), position.getY()+getYSize(), position.getZ()+getZSize()));
		}else{
			return new zLineSegment(
					new Point(position.getX(), position.getY(), position.getZ()), 
					new Point(position.getX(), position.getY(), position.getZ()+getZSize()));
		}
	}

	@Override
	public Rectangle2D toRectangle2D() {
		
		return new Rectangle2D.Double(position.getY(), position.getZ(), getYSize(), getZSize());
	}
	
	public YZRectangle getOverlaped(YZRectangle yzRectangle){
		Rectangle2D thisRectangle2D  = this.toRectangle2D();
		Rectangle2D yzRectangle2D = yzRectangle.toRectangle2D();
		
		Rectangle2D intersection2D = thisRectangle2D.createIntersection(yzRectangle2D);
		Point intersectionPosition =  new Point(position.getX(),(int)intersection2D.getX(), (int)intersection2D.getY());
		return new YZRectangle(intersectionPosition, (int)intersection2D.getWidth(), (int)intersection2D.getHeight(), this.isPositiveFaced);
		
	}
	public int getMinY(){
		return this.position.getY();
	}
	public int getMaxY(){
		return this.position.getY()+this.getYSize();
	}
	public int getMaxZ(){
		return this.position.getZ()+this.getZSize();
	}
	public int getMinZ(){
		return this.position.getZ();
	}
	
	public List<Point2D> getPoint2D() {
		List<Point2D> result = new ArrayList<Point2D>();
		result.add(new Point2D.Double(getMinY(), getMinZ()));
		result.add(new Point2D.Double(getMaxY(), getMinZ()));
		result.add(new Point2D.Double(getMaxY(), getMaxZ()));
		result.add(new Point2D.Double(getMinY(), getMaxZ()));
		
		
		return result;
	} 
	public Point2D  getPoint2D (RectanglePoint e){
//		System.out.println(this.centerPoint.z()-this.zSize/2);
		if(e==RectanglePoint.TOPLEFT){
			return new Point2D.Double(getMinY(), getMaxZ());
		}else if (e== RectanglePoint.TOPRIGHT){
			return new Point2D.Double(getMaxY(), getMaxZ());
		}else if(e==RectanglePoint.BOTTOMLEFT){
			return new Point2D.Double(getMinY(), getMinZ());
		}else if (e== RectanglePoint.BOTTOMRIGHT){
			return new Point2D.Double(getMaxY(), getMinZ());
		} 

		return null;
		
	}
//	public Rectangle2DRelation findRelation(YZRectangle yzRectangle){
//		Rectangle2D this2D = this.toRectangle2D();
//		Rectangle2D xyRectangle2D = yzRectangle.toRectangle2D();
//		
//		if(xyRectangle2D.contains(this2D))return Rectangle2DRelation.INSIDE;
//		if(this2D.contains(xyRectangle2D)) return Rectangle2DRelation.CONTAIN;
//		if((this.getMinY() == yzRectangle.getMaxY()
//				|| this.getMaxY() == yzRectangle.getMinY())
//				&& (yzRectangle.getMinZ() <= this.getMaxZ()  
//						&& yzRectangle.getMinZ() >= this.getMinZ() 
//					||yzRectangle.getMaxZ() <= this.getMaxZ()  
//						&& yzRectangle.getMaxZ() >= this.getMinZ())){
//			return Rectangle2DRelation.TOUCHING;
//		}else if((this.getMinZ() == yzRectangle.getMaxZ()
//				|| this.getMaxZ() == yzRectangle.getMinZ())
//				&& ((yzRectangle.getMinY() <= this.getMaxY()  
//						&& yzRectangle.getMinY() >= this.getMinY()) 
//					||(yzRectangle.getMaxY() <= this.getMaxY()  
//						&& yzRectangle.getMaxY() >= this.getMinY()))){
//			return Rectangle2DRelation.TOUCHING;
//		}else if(this2D.intersects(xyRectangle2D)){
//			int pointContain =0 ;
////			System.out.println(this.getPoint2D());
////			System.out.println(xyRectangle.getPoint2D());
//			for(Point2D p2D : yzRectangle.getPoint2D()){
//				if(this2D.contains(p2D)){
////					System.out.println(p2D);
//					pointContain++;
//				}
//				
//			}
//			if(pointContain==0){
//				return Rectangle2DRelation.ZEROINSIDE;
//			}else if(pointContain==1){
//				return Rectangle2DRelation.ONEINSIDE;
//			}else if(pointContain==2){
//				return Rectangle2DRelation.TWOINSIDE;
//			}
//			
//		}
//		return Rectangle2DRelation.OUTSIDE;
//		
//	}
	
	public List<YZRectangle> getLeftOverInside(YZRectangle yzRectangle) {
		List<YZRectangle> result = new ArrayList<YZRectangle>();
		
		int leftOverY =-1;
		int leftOverZ =-1;
		int leftOverPositionY =-1;
		int leftOverPositionZ =-1;
		
		leftOverY = yzRectangle.getMinY() - this.getMinY();
		leftOverZ = this.getZSize();
		leftOverPositionY = this.getMinY();
		leftOverPositionZ = this.getMinZ();
		
		if(leftOverY>0 && leftOverZ>0){
			result.add(new YZRectangle(new Point(this.position.getX(),leftOverPositionY,leftOverPositionZ),
					leftOverY, leftOverZ, this.isPositiveFaced));
			
		}
		
		leftOverY = yzRectangle.getYSize();
		leftOverZ = yzRectangle.getMinZ() - this.getMinZ();
		leftOverPositionY = yzRectangle.getMinY();
		leftOverPositionZ = this.getMinZ();
		
		if(leftOverY>0 && leftOverZ>0){
			result.add(new YZRectangle(new Point(this.position.getX(),leftOverPositionY,leftOverPositionZ),
					leftOverY, leftOverZ, this.isPositiveFaced));
			
		}
		
		leftOverY = yzRectangle.getYSize();
		leftOverZ = this.getMaxZ() - yzRectangle.getMaxZ();
		leftOverPositionY = yzRectangle.getMinY();
		leftOverPositionZ = yzRectangle.getMaxZ();
		
		if(leftOverY>0 && leftOverZ>0){
			result.add(new YZRectangle(new Point(this.position.getX(),leftOverPositionY,leftOverPositionZ),
					leftOverY, leftOverZ, this.isPositiveFaced));
			
		}
		
		leftOverY = this.getMaxY() - yzRectangle.getMaxY();
		leftOverZ = this.getZSize();
		leftOverPositionY = yzRectangle.getMaxY();
		leftOverPositionZ = this.getMinZ();
		
		if(leftOverY>0 && leftOverZ>0){
			result.add(new YZRectangle(new Point(this.position.getX(),leftOverPositionY,leftOverPositionZ),
					leftOverY, leftOverZ, this.isPositiveFaced));
			
		}
		
		
		
		
		return result;
		
	}
	public  List<YZRectangle> getLeftOverOnePoint(YZRectangle yzRectangle){
		List<YZRectangle> result = new ArrayList<YZRectangle>();
		Rectangle2D thisRectangle2D = this.toRectangle2D();
//		Rectangle2D yzRectangle2D = this.toRectangle2D();
		Rectangle2D intersection = this.getOverlaped(yzRectangle).toRectangle2D();
		int leftOver1Y  = (int)(thisRectangle2D.getWidth()  - intersection.getWidth());
		int leftOver1Z  = (int)(thisRectangle2D.getHeight());
		
		int leftOver2Y  = (int)(intersection.getWidth());
		int leftOver2Z  = (int)(thisRectangle2D.getHeight() - intersection.getHeight());
		
		int leftOver1PositionY =-1;
		int leftOver1PositionZ =-1;
		int leftOver1PositionX =this.position.getX();
		int leftOver2PositionY =-1;
		int leftOver2PositionZ =-1;
		int leftOver2PositionX =this.position.getX();
		
		if(thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPLEFT))){
			leftOver1PositionY = this.getMinY();
			leftOver1PositionZ = this.getMinZ();
			
			leftOver2PositionY = yzRectangle.getMinY();
			leftOver2PositionZ = yzRectangle.getMaxZ();
			
			
		}else if(thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPRIGHT))){
			leftOver1PositionY = yzRectangle.getMaxY();
			leftOver1PositionZ = this.getMinZ();
			
			leftOver2PositionY = this.getMinY();
			leftOver2PositionZ = yzRectangle.getMaxZ();
		}else if(thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT))){
			leftOver1PositionY = this.getMinY();
			leftOver1PositionZ = this.getMinZ();
			
			leftOver2PositionY = yzRectangle.getMinY();
			leftOver2PositionZ = this.getMinZ();
		}else if(thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.BOTTOMRIGHT))){
			leftOver1PositionY = yzRectangle.getMaxY();
			leftOver1PositionZ = this.getMinZ();
			
			leftOver2PositionY = this.getMinY();
			leftOver2PositionZ = this.getMinZ();
		}
		
		if(leftOver1Y >0 && leftOver1Z >0 ){
			Point position = new Point(leftOver1PositionX,leftOver1PositionY, leftOver1PositionZ );
			result.add(new YZRectangle(position,leftOver1Y,leftOver1Z,this.isPositiveFaced));
		}
		if(leftOver2Y >0 && leftOver2Z >0 ){
			Point position = new Point(leftOver2PositionX,leftOver2PositionY, leftOver2PositionZ);
			result.add(new YZRectangle(position,leftOver2Y,leftOver2Z,this.isPositiveFaced));
		}
		
		
		
		return result;
		
		
	}
	
	public List<YZRectangle> getLeftOverTwoPoint(YZRectangle yzRectangle){
		List<YZRectangle> result = new ArrayList<YZRectangle>();
		Rectangle2D thisRectangle2D = this.toRectangle2D();
//		Rectangle2D yzRectangle2D = this.toRectangle2D();
		int leftOver1Y = -1;
		int leftOver1Z = -1;
		
		int leftOver2Y = -1;
		int leftOver2Z = -1;
		int leftOver2PositionY =-1;
		int leftOver2PositionZ =-1;
		int leftOver2PositionX =this.position.getX();
		
		int leftOver3X = -1;
		int leftOver3Z = -1;
		int leftOver3PositionY =-1;
		int leftOver3PositionZ =-1;
		int leftOver3PositionX =this.position.getX();
		
		Point leftOver1Position = this.position;
		if((thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
				thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPRIGHT)))
				||  (thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT)) && 
						thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.BOTTOMRIGHT)))){
			leftOver1Y = yzRectangle.getMinY() - this.getMinY();
			leftOver1Z = this.getZSize();
			
			leftOver2Y = yzRectangle.getYSize();
			leftOver2PositionY = yzRectangle.getMinY();
			
			leftOver3X = this.getMaxY() - yzRectangle.getMaxY();
			leftOver3Z = this.getZSize();
			leftOver3PositionY = yzRectangle.getMaxY();
			
			if((thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
					thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPRIGHT)))){
				leftOver2Z = this.getMaxZ() - yzRectangle.getMaxZ();
				leftOver2PositionZ = yzRectangle.getMaxZ();
				leftOver3PositionZ = this.getMinZ();
			}else{
				leftOver2Z = yzRectangle.getMinZ() - this.getMinZ();
				leftOver2PositionZ = this.getMinZ();
				leftOver3PositionZ = this.getMinZ();
			}
			
			
		}else if((thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
				thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT))
				||(thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPRIGHT)) && 
						thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.BOTTOMRIGHT))))){
			
			leftOver1Y = this.getYSize();
			leftOver1Z = yzRectangle.getMinZ()- this.getMinZ();
			
			leftOver2Z = yzRectangle.getZSize();
			leftOver2PositionZ = yzRectangle.getMinZ();

			leftOver3X = this.getYSize();
			leftOver3Z = this.getMaxZ() -  yzRectangle.getMaxZ();
			leftOver3PositionY = this.getMinY();
			leftOver3PositionZ = yzRectangle.getMaxZ();
			
			if((thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
					thisRectangle2D.contains(yzRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT)))){
				leftOver2PositionY = this.getMinY();
				leftOver2Y =  yzRectangle.getMinY() - this.getMinY();
				
			}else{
				leftOver2PositionY = yzRectangle.getMaxY();
				leftOver2Y =  this.getMinY()-yzRectangle.getMinY() ;
			}
			
		
		
		}
		
		if(leftOver1Y >0  && leftOver1Z >0){
			
			result.add(new YZRectangle(leftOver1Position, leftOver1Y, leftOver1Z, this.isPositiveFaced));
			
		}
		
		if(leftOver2Y >0  && leftOver2Z >0){
			Point position = new Point(leftOver2PositionX, leftOver2PositionY,  leftOver2PositionZ);
			result.add(new YZRectangle(position, leftOver2Y, leftOver2Z, this.isPositiveFaced));
			
		}
		
		if(leftOver3X >0  && leftOver3Z >0){
			Point position = new Point(leftOver3PositionX,leftOver3PositionY, leftOver3PositionZ);
			result.add(new YZRectangle(position, leftOver3X, leftOver3Z, this.isPositiveFaced));
			
		}
		return result;
	}
	
	public List<YZRectangle> getLeftOverZeroPoint(YZRectangle yzRectangle){
		List<YZRectangle> result = new ArrayList<YZRectangle>();
//		Rectangle2D thisRectangle2D = this.toRectangle2D();
		Rectangle2D xzRectangle2D = yzRectangle.toRectangle2D();
		int leftOver1Y = -1;
		int leftOver1Z = -1;
		int leftOverPosition1Y = -1;
		int leftOverPosition1Z = -1;
		
		int leftOver2Y = -1;
		int leftOver2Z = -1;
		int leftOverPosition2Y = -1;
		int leftOverPosition2Z = -1;
		
		
		
		if((xzRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
				xzRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPRIGHT)) )
				||(xzRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMLEFT)) &&
						xzRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMRIGHT)))){
			leftOver1Y = this.getYSize();
			leftOverPosition1Y = this.getMinY();
			if(xzRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
					xzRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPRIGHT))){
				leftOver1Z = yzRectangle.getMinZ()-this.getMinZ();
				leftOverPosition1Z = this.getMinZ();
				
			}else{
				leftOver1Z = this.getMaxZ() - yzRectangle.getMaxZ();
				leftOverPosition1Z =yzRectangle.getMaxZ();
			}
		}else if((xzRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
				xzRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMLEFT)) )
				||(xzRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPRIGHT)) &&
						xzRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMRIGHT)))){
			leftOver1Z = this.getZSize();
			leftOverPosition1Z = this.getMinZ();
			if(xzRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
					xzRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMLEFT))){
				leftOver1Y = this.getMaxY()- yzRectangle.getMaxY();
				leftOverPosition1Y = yzRectangle.getMaxY();
				
			}else{
				leftOver1Y = yzRectangle.getMinY() - this.getMinY();
				leftOverPosition1Y = this.getMinY();
			}
		}else if(this.getMaxZ() > yzRectangle.getMaxZ()){
			leftOver1Y = this.getYSize();
			leftOver1Z = yzRectangle.getMinZ() - this.getMinZ();
			leftOverPosition1Y  = this.getMinY();
			leftOverPosition1Z  = this.getMinZ();
			
			leftOver2Y = this.getYSize();
			leftOver2Z = this.getMaxZ() - yzRectangle.getMaxZ();
			leftOverPosition2Y = this.getMinY();
			leftOverPosition2Z = yzRectangle.getMaxZ();
			
		}else{
			leftOver1Y = yzRectangle.getMinY() - this.getMinY();
			leftOver1Z = this.getZSize();
			leftOverPosition1Y  = this.getMinY();
			leftOverPosition1Z  = this.getMinZ();
			
			leftOver2Y = this.getMaxY() - yzRectangle.getMaxY();
			leftOver2Z = this.getZSize();
			leftOverPosition2Y = yzRectangle.getMaxY();
			leftOverPosition2Z = this.getMinZ();
		}
		
		if(leftOver1Y>0 && leftOver1Z>0){
			result.add(new YZRectangle(new Point(this.position.getX(),leftOverPosition1Y,leftOverPosition1Z),
					leftOver1Y,leftOver1Z, this.isPositiveFaced ));
			
		}
		
		if(leftOver2Y>0 && leftOver2Z>0){
			result.add(new YZRectangle(new Point(this.position.getY(),leftOverPosition2Y,leftOverPosition2Z),
					leftOver2Y,leftOver2Z, this.isPositiveFaced ));
			
		}
		
		
		return result;
	}
	public YZRectangle reverse(){
		this.isPositiveFaced = !this.isPositiveFaced;
		return this;
	}
}
